home *** CD-ROM | disk | FTP | other *** search
- page ,132
- title - atfastky.asm (hardware keyboard accelerator)
-
-
- ;---------- ATFASTKY.ASM -- AT HARDWARE KEYBOARD ACCELERATOR
- ;
- ; ATFASTKY programs the keyboard of the AT and 80386 machines via
- ;the 8024 keyboard controller and sets the delay and repeat rates associated
- ;with the key repeat function. This program will not work with machines such
- ;as IBM PC's, XT's, or JR's which do not have an 8024 chip, or on machines
- ;whose keyboards do not support this feature. The program is invoked
- ;by typing:
- ;
- ; "ATFASTKY d r" or simply "ATFASTKY"
- ;
- ; In the latter case (no command line arguments), a default combination
- ;of d=0 r=0 is assumed (shortest delay, fastest repeat). If you want to
- ;change these default values, replace the 0 values where 'delay' and 'repeat'
- ;are initialized (bottom of program) with the values you want. NOTE: no
- ;error checking is done on the default values, so if you change them, make
- ;sure you replace them with valid values.
- ; In the former case, 'd' is a number 0-3 which represents the delay
- ;factor you want (the time delay between the initial key press and the
- ;activation of the repeat feature), and 'r' is a number 0-31 representing the
- ;repeat rate you want. NOTE THAT THE COMMAND LINE IS VERY SENSITIVE TO WHAT
- ;YOU TYPE. THERE MUST BE ONE AND ONLY ONE SPACE BETWEEN THE PROGRAM NAME AND
- ;THE DELAY VALUE, AS WELL AS ONE AND ONLY ONE SPACE BETWEEN THE DELAY VALUE
- ;AND THE REPEAT VALUE. ANY OTHER VARIATION (EXCEPT FOR THE EMPTY COMMAND
- ;LINE) WILL RESULT IN AN ERROR MESSAGE.
- ;
- ; The actual command byte passed to the keyboard which specifies the
- ;delay/repeat combination you want is delay*32 + repeat.
- ;
- ; |---------- REPEAT VALUES --------| |---- DELAY VALUES ----|
- ;
- ;Val(r) keys/sec Val(r) keys/sec Val(d) Time delay from 1st press
- ;
- ;0 30.0; 16 7.5 0 250ms
- ;1 26.6; 17 6.7 1 500ms
- ;2 24.0; 18 6.0 2 750ms
- ;3 21.8; 19 5.5 3 1000ms
- ;4 20.0; 20 5.0
- ;5 18.4; 21 4.6
- ;6 17.1; 22 4.3
- ;7 16.0; 23 4.0
- ;8 15.0; 24 3.7
- ;9 13.3; 25 3.3
- ;10 12.0; 26 3.0
- ;11 10.9; 27 2.7
- ;12 10.0; 28 2.5
- ;13 9.2; 29 2.3
- ;14 8.6; 30 2.1
- ;15 8.0; 31 2.0
- ;
- ;--------------------------------------------------------------------------------------------------
-
- ;---- DEFINE PROGRAM CONSTANTS ---------------------------------------------------------------------
-
- ack EQU 0FAH ;ACK value; acknowledgement byte returned by keyboard
- asciioff EQU 030H ;amount to subtract from ascii '0' to get numeric 0
- dosline EQU 082H ;location of command line arguments (after 1st space) in PSP
- doslen EQU 080H ;byte indicating length of command line
- comport8024 EQU 064H ;port number for 8024's command/status port
- ioport8024 EQU 060H ;port number for 8024's keyboard I/O port
- statmsk8024 EQU 002H ;status mask to determine that 8024's buffer is empty
- kbd_disable EQU 0ADH ;8024 command to disable the keyboard
- kbd_enable EQU 0AEH ;8024 command to re-enable the keyboard
- kbd_chgspd EQU 0F3H ;Command to the keyboard: change repeat parameters
- doscall EQU 021H ;dos interrupt
- space EQU 020H ;ASCII space character
- return EQU 00DH ;ASCII carriage return character
-
- ;---- SET UP SEGMENT ------------------------------------------------------------------------------
-
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
-
- ORG 100H
-
- ;---- PROGRAM SECTION ------------------------------------------------------------------------------
-
- atfastkey PROC NEAR
-
- ;Examine the command line length; if it's zero, jump directly to the speed setting routine. In
- ;this case it will use the default 'repeat' and 'delay' values.
-
- entry: MOV BX,0 ;clear BX
- MOV BL,doslen[BX] ;length of program's command line
- OR BL,BL ;make sure it has a length
- JNZ parse ;command line given, parse it
- JMP setspeed ;no command line given, default to fastest delay/repeat (0/0)
-
- ;Look at the first command line argument. Make sure it is only one byte long.
-
- parse: CLD ;set direction flag for string scan
- MOV DI,dosline ;move offset of first command line arg into DI
- MOV CX,0FFFFH ;move a big scan count into CX
- MOV AL,space ;character to look for (separating space between args)
- REPNE SCASB ;scan the 1st argument for its terminating space
- CMP CX,0FFFDH ;see if 1st arg is 1 byte long
- JNE err1 ;bad command line (improper 1st arg length)
-
- ;Determine the numeric value of the 1st arg ASCII character. If its not between 0 and 3
- ;then exit with an error message
-
- MOV AL,[DI-2] ;move 1st arg (single byte) into AX
- SUB AL,asciioff ;convert it to a number
- CMP AL,0 ;see if its less than 0
- JL err1 ;bad 1st argument (digit is < 0)
- CMP AL,3 ;see if its greater than 3
- JA err1 ;bad 1st argument (digit is > 3)
-
- ;First argument (delay) is valid, multiply it by 32 and save it
-
- MOV BL,32
- MUL BL ;shift 1st arg to proper position in keyboard cmd byte
- MOV delay,AL ;good 1st argument, save it in delay
-
- ;Look at the second command line argument, make sure it is only one or two characters long;
- ;if not, exit with the error message.
-
- MOV AL,return ;search for terminating carriage return; DI is already pointing
- REPNE SCASB ;to the right place as a result of the last SCASB
-
- XOR AL,AL ;So 10's digit * 10 = 0 if there is no 10's digit
- XOR DL,DL ;So 10's digit = 0 in 1's digit test
- CMP CX,0FFFBH ;see if only one digit was given
- JE X1 ;single digit given, jump to X1
- CMP CX,0FFFAH ;see if two digits were given
- JNE err1 ;bad 2nd argument (2nd argument has improper length)
-
- ;Second argument is of proper length and involves a 10's digit. Convert the 10's ASCII character
- ;into a number and make sure its valid (between 0 and 3).
-
- MOV AL,[DI-3] ;get 10's digit and convert it into a number
- SUB AL,asciioff
- CMP AL,0
- JL err1 ;bad 2nd argument (10's digit is < 0)
- CMP AL,3
- JA err1 ;bad 2nd argument (10's digit > 3)
- MOV DL,AL ;save 10's digit in DL
- MOV BL,10
- MUL BL ;multiply good 2nd argument 10's digit by 10
-
- ;Evaluate second arguments 1's digit. Convert it to a number and make sure its valid,
- ;i.e. 10's digit 0-2 -> 1's digit 0-9, 10'd digit 3 -> 1's digit 0-1
-
-
- X1: MOV BL,[DI-2] ;get 1's digit and convert it into a number
- SUB BL,asciioff
- CMP BL,0
- JL err1 ;bad 2nd argument (1's digit is < 0)
- CMP BL,9
- JA err1 ;bad 2nd argument (1's digit is > 9)
-
- CMP DL,3 ;see if 10's digit is 3
- JB calc_2nd ;(it's 0 if we jumped to X1)
- CMP BL,2
- JB calc_2nd ;if no jump, 2nd arg is bad (arg > 31)
- err1: JMP com_error
-
- ;Combine the 10's digit and 1's digit to form the 'repeat' value and save it
-
- calc_2nd: ADD AL,BL
- MOV repeat,AL
-
- ;Now we're ready to talk to the keyboard. First we must remove any stray keys
- ;which might be left in the 8024's buffer by flushing it.
-
- ;---- FLUSH THE 8024's BUFFER --------------------------------------------------------
-
- setspeed: MOV AH,01H ;see if there's a keystroke waiting to be read
- INT 16H
- JZ fastkey
-
- ;read characters out of the keyboard buffer until its empty
-
- flush: XOR AH,AH ;there is; read it
- INT 16H
- MOV AH,01H ;see if there's another
- INT 16H
- JNZ flush ;loop until all characters are flushed
-
- ;confirm that the 8042 buffer is empty
-
- fastkey: IN AL,comport8024 ;read the 8042 keyboard controller
- AND AL,statmsk8024 ;wait for its input buffer to be empty
- JNZ flush ;on the off chance the user got a
- ;keystroke in edgewise
-
- ;---- PROGRAM THE KEYBOARD -------------------------------------------------------------
-
- ;initialize and carry out the dialogue with the keyboard
-
- MOV AL,kbd_disable ;disable the keyboard
- OUT comport8024,AL
-
- we1: IN AL,comport8024 ;wait for 8042 input buffer to empty again
- AND AL,statmsk8024
- JNZ we1
-
- MOV AL,kbd_chgspd ;tell the keyboard you want to change the repeat rate
- OUT ioport8024,AL
-
- wack1: IN AL,ioport8024 ;wait for an ack from the keyboard
- CMP AL,ack
- JNE wack1
-
- MOV AL,repeat ;calculate the speed
- MOV BL,delay
- OR AL,BL
- OUT ioport8024,AL ;send delay/repeat byte to keyboard
-
- wack2: IN AL,ioport8024 ;wait for another ack
- CMP AL,ack
- JNE wack2
-
- we2: IN AL,comport8024 ;wait for an empty 8042 buffer
- AND AL,statmsk8024
- JNZ we2
-
- MOV AL,kbd_enable
- OUT comport8024,AL ;re-enable keyboard
- JMP exit
-
- com_error: LEA DX,errmsg
- MOV AH,09H ;DOS print string function
- INT doscall
- exit: ret
-
- ;---- STATIC VARIABLES --------------------------------------------------------------------------
-
- errmsg db 13,10
- db 'ATFASTKY error - USAGE: "ATFASTKY delay repeat" (delay:0-3, repeat:0-31)'
- db 13,10,'$'
- delay db 0 ;store repeat value, default = 0
- repeat db 0 ;store repeat value, default = 0
-
- atfastkey ENDP
- CSEG ENDS
- END entry
-